package com.chuanwei.service.Impl;

import com.chuanwei.mapper.EmpExprMapper;
import com.chuanwei.mapper.EmpMapper;
import com.chuanwei.pojo.*;
import com.chuanwei.service.EmpLogService;
import com.chuanwei.service.EmpService;
import com.chuanwei.utils.JwtUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.event.TransactionalEventListener;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpMapper empMapper;

    @Autowired
    private EmpExprMapper empExprMapper;

    @Autowired
    private EmpLogService empLogService;


    @Override
    public PageResult<Emp> page(EmpQueryParam empQueryParam) {

        //-------------原始分页查询-------------
      /*  //1.调用mapper接口查询总记录数
        Long total = empMapper.count();


        //2.调用mapper接口查询结果列标
        List<Emp> list = empMapper.list((page - 1) * pageSize, pageSize);


        //3.封装结果
        return new PageResult<Emp>(total, list);*/

        /**
         * 基于pageHelper分页查询
         */
        //1.设置分页参数
        PageHelper.startPage(empQueryParam.getPage(), empQueryParam.getPageSize());

        //2.执行查询
        List<Emp> emplist = empMapper.list(empQueryParam );

        //3.解析查询结果，并封装数据（ PageHelper会自动把解析分页解析结果封装到Page对象中）
        Page<Emp> p  = (Page<Emp>) emplist;//Page<E> extends ArrayList<E>， ArrayList<E>实现了List<E>所以可以强转为Page<Emp>

        return new PageResult<Emp>(p.getTotal(),p.getResult());



    }


    @Transactional()  //事务管理
    @Override
    public void save(Emp emp) {
        try {
            //保存员工的基本信息， 并补全基础信息
            emp.setCreateTime(LocalDateTime.now());
            emp.setUpdateTime(LocalDateTime.now());

            empMapper.insert(emp);

            //批量保存员工的工作经历信息

            //先拿到员工的工作经历（一个员工可以有多段工作经历，一个员工也可能没有工作经历，所以加一个条件判断，如果有工作经历就添加，如果没有-工作经历就不添加）
            List<EmpExpr> exprList = emp.getExprList();
            if (!CollectionUtils.isEmpty(exprList)){
                //拿到主键id为集合里的元素赋值，遍历集合，把主键id赋值给EmpExpr中的empId
                exprList.forEach(empExpr -> {
                    empExpr.setEmpId(emp.getId());
                });
                empExprMapper.insertBatch(exprList);//批量保存
            }
        } finally {
            //记录操作日志
            EmpLog empLog = new EmpLog(null, LocalDateTime.now(), "新增员工：" + emp);
            empLogService.insertLog(empLog);
        }



    }
    @Transactional(rollbackFor = {Exception.class}) //出现异常都要回滚
    @Override
    public void deleteByIds(List<Integer> ids) {//多次操作要么成功要么失败，所以添加事务控制
        //1.批量删除员工的基本信息
        empMapper.deletByIds(ids);

        //2.批量删除员工的基本工作经历信息
        empExprMapper.deleteByEmpIds(ids);

    }

    @Override
    public Emp getInfo(Integer id) {
       return empMapper.getById(id);
    }

    @Transactional(rollbackFor =Exception.class)
    @Override
    public void update(Emp emp) {
        //1.根据id修改员工的基本信息（附带更新最后操作时间）
        emp.setUpdateTime(LocalDateTime.now());//更新为当前系统的操作时间
        empMapper.updateById(emp);

       //2. 根据id修改员工的工作经历信息（先删除 再添加）
        //2.1.先根据员工id删除员工原来的工作经历

        empExprMapper.deleteByEmpIds(Arrays.asList(emp.getId()));

        //2.2再根据id添加这个员工的新的工作经历

        List<EmpExpr> exprList = emp.getExprList();
        if (!CollectionUtils.isEmpty(exprList)){//如果前端传来的这人新增加的工作经历集合不是空的，才需要往数据库增加新的工作经历
            exprList.forEach(empExpr -> empExpr.setEmpId(emp.getId()));//指定这段工作经历是哪个员工的工作经历，主键关联
            empExprMapper.insertBatch(exprList);
        }
    }

    @Override
    public LoginInfo login(Emp emp) {
        //1.调用mapper接口查询员工信息
        Emp loginEmp = empMapper.selectByUsernameAndPassword(emp);

        //2.判断是否存在这个员工，如果存在，组装登录成功信息
        if (loginEmp != null){
            log.info("登录成功：{}", loginEmp);

            //生成jwt令牌
            Map<String, Object> claims  =  new HashMap<>();

            claims.put("id", loginEmp.getId());
            claims.put("username", loginEmp.getUsername());

            String jwt = JwtUtils.generateJwt(claims);//参数是自定义的信息


            LoginInfo loginInfo = new LoginInfo(loginEmp.getId(), loginEmp.getUsername(), loginEmp.getName(), jwt);

            return loginInfo;
        }

        //3.
        log.info("登录失败：{}", emp);
        return null;
    }
}